package com.epam.klymanov.tools;

import java.util.ArrayList;

public class AreaBuilder {
	int[][] matrix;
	boolean[][] visitedSpots;// shows if the spot was visited

	public AreaBuilder(int[][] matrix) {
		super();
		this.matrix = matrix;
		
	}

	public ArrayList<Spot> getArea(int x, int y, int startPollution, int endPollution) {
		visitedSpots = new boolean[matrix.length][matrix[0].length];
		int lastPos =0;
		int curentX ;
		int curentY;
	if(isPassed(x,y,startPollution, endPollution)){
		curentX = x;
		curentY = y;
	}
	else{
		return null;
	}
		
		ArrayList<Spot> area = new ArrayList<Spot>();
		while(true){
			if(isPassed(curentX, curentY, startPollution, endPollution)){
				area.add(new Spot(curentX, curentY, matrix[curentX][curentY]));
				lastPos = area.size()-1;
				visitedSpots[curentX][curentY] = true;
				if(isPassed(curentX+1, curentY, startPollution, endPollution)){curentX++;}
				else if(isPassed(curentX+1, curentY+1, startPollution, endPollution)){curentX++; curentY++;}
				else if(isPassed(curentX, curentY+1, startPollution, endPollution)){curentY++;}
				else if(isPassed(curentX-1, curentY+1, startPollution, endPollution)){curentX--; curentY++;}
				else if(isPassed(curentX-1, curentY, startPollution, endPollution)){curentX--;}
				else if(isPassed(curentX-1, curentY-1, startPollution, endPollution)){curentX--; curentY--;}
				else if(isPassed(curentX, curentY-1, startPollution, endPollution)){curentY--;}
				else if(isPassed(curentX+1, curentY-1, startPollution, endPollution)){curentX++;curentY--;}
				else{
					curentX = area.get(lastPos).getX();
					curentY = area.get(lastPos).getY();
					lastPos--;
				}
				
			}else{
				
				visitedSpots[curentX][curentY] = true;
				if(isPassed(curentX+1, curentY, startPollution, endPollution)){curentX++;}
				else if(isPassed(curentX+1, curentY+1, startPollution, endPollution)){curentX++; curentY++;}
				else if(isPassed(curentX, curentY+1, startPollution, endPollution)){curentY++;}
				else if(isPassed(curentX-1, curentY+1, startPollution, endPollution)){curentX--; curentY++;}
				else if(isPassed(curentX-1, curentY, startPollution, endPollution)){curentX--;}
				else if(isPassed(curentX-1, curentY-1, startPollution, endPollution)){curentX--; curentY--;}
				else if(isPassed(curentX, curentY-1, startPollution, endPollution)){curentY--;}
				else if(isPassed(curentX+1, curentY-1, startPollution, endPollution)){curentX++;curentY--;}
				else{
					
					curentX = area.get(lastPos).getX();
					curentY = area.get(lastPos).getY();
					lastPos--;
				}
			
			}
			
			if((curentX == x)&&(curentY==y)){
				if(isPassed(curentX+1, curentY, startPollution, endPollution)){curentX++;}
				else if(isPassed(curentX+1, curentY+1, startPollution, endPollution)){curentX++; curentY++;}
				else if(isPassed(curentX, curentY+1, startPollution, endPollution)){curentY++;}
				else if(isPassed(curentX-1, curentY+1, startPollution, endPollution)){curentX--; curentY++;}
				else if(isPassed(curentX-1, curentY, startPollution, endPollution)){curentX--;}
				else if(isPassed(curentX-1, curentY-1, startPollution, endPollution)){curentX--; curentY--;}
				else if(isPassed(curentX, curentY-1, startPollution, endPollution)){curentY--;}
				else if(isPassed(curentX+1, curentY-1, startPollution, endPollution)){curentX++;curentY--;}
				else{
					break;
				}
				
				
			}
		}
		

		return area;
	}
	
	private boolean isInPollutionArea(int spot, int startPollution, int endPollution){
		if(spot< startPollution){return false;}
		if(spot> endPollution){return false;}
		
		return true;
	}
	
	private boolean isInsider(int x, int y, int startPollution, int endPollution){
		if(!isLowPassed(x+1, y, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x+1, y+1, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x, y+1, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x-1, y+1, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x-1, y, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x-1, y-1, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x, y-1, startPollution, endPollution)){return false;}
		else if(!isLowPassed(x+1, y-1, startPollution, endPollution)){return false;}
		else{
			return true;
		}
		
	}
	
	private boolean isLowPassed(int x, int y, int startPollution, int endPollution){
		if(y>= matrix[0].length){return false;}
		if(x>= matrix.length){return false;}
		if(y< 0){return false;}
		if(x<0){return false;}
		if(!isInPollutionArea(matrix[x][y],startPollution, endPollution)){return false;}
		return true;
	}
	
	
	private boolean isPassed(int x, int y, int startPollution, int endPollution){
		if(y>= matrix[0].length){return false;}
		if(x>= matrix.length){return false;}
		if(y< 0){return false;}
		if(x<0){return false;}
		if(visitedSpots[x][y]){return false;}
		if(!isInPollutionArea(matrix[x][y],startPollution, endPollution)){return false;}
		if(isInsider(x,y,startPollution, endPollution)){return false;}
		return true;
	}
	
	

}
